home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xpaint-2.1.1
/
cutCopyPaste.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
14KB
|
552 lines
/* +-------------------------------------------------------------------+ */
/* | Copyright 1993, David Koblas (koblas@netcom.com) | */
/* | | */
/* | Permission to use, copy, modify, and to distribute this software | */
/* | and its documentation for any purpose is hereby granted without | */
/* | fee, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. There is no | */
/* | representations about the suitability of this software for | */
/* | any purpose. this software is provided "as is" without express | */
/* | or implied warranty. | */
/* | | */
/* +-------------------------------------------------------------------+ */
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <X11/Xatom.h>
#include "Paint.h"
#include "xpaint.h"
#include "misc.h"
#include "menu.h"
#include "palette.h"
#include "image.h"
Image *ImageSmooth(Image *);
Image *ImageSharpen(Image *);
Image *ImageInvert(Image *);
Image *ImageEdge(Image *);
Image *ImageEmbose(Image *);
Image *ImageOilPaint(Image *);
extern void *GraphicGetData(Widget);
static Boolean selectionOwner = False;
/*
** This really should be a "local" or malloced variable
*/
typedef struct {
Pixmap pixmap;
int count;
int width, height, depth;
} selectInfo;
static void setToSelectOp()
{
static String names[2] = { "selectBox", "selectArea" };
OperationSet(names, 2);
}
static void selectionLost(Widget w, Atom *selection)
{
selectionOwner = False;
}
static void selectionDone(Widget w, Atom *selection, Atom *target)
{
/* empty */
}
static Boolean selectionConvert(Widget w, Atom *selection, Atom *target,
Atom *type, XtPointer *value, unsigned long *len,
int *format)
{
Pixmap src = Global.region.pix;
Pixmap *pix, np;
GC gc;
int wth, hth, dth;
if (src == None)
return False;
if (*target != XA_PIXMAP && *target != XA_BITMAP)
return False;
pix = XtNew(Pixmap);
GetPixmapWHD(XtDisplay(w), src, &wth, &hth, &dth);
np = XCreatePixmap(XtDisplay(w), XtWindow(w), wth, hth, dth);
gc = XCreateGC(XtDisplay(w), np, 0, 0);
XCopyArea(XtDisplay(w), src, np, gc, 0, 0, wth, hth, 0, 0);
XFreeGC(XtDisplay(w), gc);
*pix = np;
*type = XA_PIXMAP;
*len = 1;
*format = 32;
*value = (XtPointer)pix;
return True;
}
void StdCopyCallback(Widget w, XtPointer paintArg, String *nm, XEvent *event)
{
Widget paint = (Widget)paintArg;
Pixmap pix, mask;
int width, height;
if (!PwRegionGet(paint, &pix, &mask))
return;
GetPixmapWHD(XtDisplay(paint), pix, &width, &height, NULL);
if (Global.region.pix != None)
XFreePixmap(XtDisplay(paint), Global.region.pix);
if (Global.region.mask != None)
XFreePixmap(XtDisplay(paint), Global.region.mask);
Global.region.pix = pix;
Global.region.mask = mask;
Global.region.width = width;
Global.region.height = height;
XtVaGetValues(paint, XtNcolormap, &Global.region.cmap, NULL);
selectionOwner = XtOwnSelection(paint, XA_PRIMARY, Global.currentTime,
selectionConvert, selectionLost, selectionDone);
}
static void stdPasteCB(Widget paint, XtPointer infoArg, Atom *selection, Atom *type,
XtPointer value, unsigned long *len, int *format)
{
selectInfo *info = (selectInfo*)infoArg;
Display *dpy = XtDisplay(paint);
XRectangle rect;
Pixmap pix;
Colormap cmap;
Pixmap newMask = None;
GC gc;
if (type != NULL) {
info->count--;
if (*type == XA_BITMAP) {
int wth, hth, dth;
Pixmap pix = *(Pixmap*)value;
GetPixmapWHD(dpy, pix, &wth, &hth, &dth);
if (info->pixmap == None ||
info->depth < dth) {
info->pixmap = pix;
info->width = wth;
info->height = hth;
info->depth = dth;
}
} else if (*type == XA_PIXMAP) {
int wth, hth, dth;
Pixmap pix = *(Pixmap*)value;
GetPixmapWHD(dpy, pix, &wth, &hth, &dth);
if (info->pixmap == None ||
info->depth < dth) {
info->pixmap = pix;
info->width = wth;
info->height = hth;
info->depth = dth;
}
}
/*
** Are there more possible selections comming?
*/
if (info->count != 0)
return;
/*
** Now that we have gotten all of the selections
** use the best one.
*/
if (info->pixmap != None) {
Pixmap np;
GC gc;
if (Global.region.pix != None)
XFreePixmap(dpy, Global.region.pix);
if (Global.region.mask != None)
XFreePixmap(dpy, Global.region.mask);
if (Global.region.image != NULL)
ImageDelete((Image*)Global.region.image);
Global.region.pix = None;
Global.region.mask = None;
Global.region.image = NULL;
np = XCreatePixmap(dpy, XtWindow(paint),
info->width, info->height, info->depth);
gc = XCreateGC(dpy, np, 0, 0);
XCopyArea(dpy, info->pixmap, np, gc,
0, 0,
info->width, info->height,
0, 0);
XFreeGC(dpy, gc);
Global.region.width = info->width;
Global.region.height = info->height;
Global.region.pix = np;
if (info->depth == 1)
Global.region.cmap = -1;
else
Global.region.cmap = DefaultColormapOfScreen(XtScreen(paint));
}
XtFree((XtPointer)info);
}
/*
** No valid selections anywhere or we own the selection.
*/
if (Global.region.pix == None && Global.region.image == NULL)
return;
rect.x = 0;
rect.y = 0;
rect.width = Global.region.width;
rect.height = Global.region.height;
if (Global.region.mask != None) {
newMask = XCreatePixmap(dpy, XtWindow(paint), rect.width, rect.height, 1);
gc = XCreateGC(dpy, newMask, 0, 0);
XCopyArea(dpy, Global.region.mask, newMask, gc, 0, 0, rect.width, rect.height, 0, 0);
XFreeGC(dpy, gc);
} else if (Global.region.image != NULL && ((Image*)Global.region.image)->maskData != NULL) {
newMask = ImageMaskToPixmap(paint, (Image*)Global.region.image);
}
XtVaGetValues(paint, XtNcolormap, &cmap, NULL);
if (cmap != Global.region.cmap) {
Image *image;
Pixmap npix = None;
if (rect.width * rect.height > 1024)
StateSetBusy(True);
if (Global.region.pix == None) {
image = (Image*)Global.region.image;
image->refCount++;
} else {
image = PixmapToImage(paint, Global.region.pix, Global.region.cmap);
}
ImageToPixmapCmap(image, paint, &npix, cmap);
PwRegionSet(paint, &rect, npix, newMask);
if (rect.width * rect.height > 1024)
StateSetBusy(False);
} else {
int depth;
XtVaGetValues(paint, XtNdepth, &depth, NULL);
pix = XCreatePixmap(dpy, XtWindow(paint), rect.width, rect.height, depth);
gc = XtGetGC(paint, 0, 0);
XCopyArea(dpy, Global.region.pix, pix, gc, 0, 0, rect.width, rect.height, 0, 0);
XtReleaseGC(paint, gc);
PwRegionSet(paint, &rect, pix, newMask);
}
setToSelectOp();
}
void StdPasteCallback(Widget w, XtPointer paintArg, XtPointer junk)
{
Widget paint = (Widget)paintArg;
int flg = True;
if (!selectionOwner) {
static Atom targets[2] = { XA_PIXMAP, XA_BITMAP };
XtPointer data[2];
selectInfo *info = XtNew(selectInfo);
info->count = XtNumber(targets);
info->pixmap = None;
data[0] = (XtPointer)info;
data[1] = (XtPointer)info;
XtGetSelectionValues(paint, XA_PRIMARY, targets, 2,
stdPasteCB, data, Global.currentTime);
} else {
stdPasteCB(paint, NULL, NULL, NULL, 0, NULL, NULL);
}
}
void StdClearCallback(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
PwRegionClear(paint);
}
void StdCutCallback(Widget w, XtPointer paintArg, String *nm, XEvent *event)
{
StdCopyCallback(w, paintArg, nm, event);
StdClearCallback(w, paintArg, NULL);
}
void StdDuplicateCallback(Widget w, XtPointer paintArg, XtPointer junk2)
{
XRectangle rect;
Widget paint = (Widget)paintArg;
Pixmap pix, mask;
int width, height;
if (!PwRegionGet(paint, &pix, &mask))
return;
GetPixmapWHD(XtDisplay(paint), pix, &width, &height, NULL);
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
PwRegionSet(paint, &rect, pix, mask);
}
void StdSelectAllCallback(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
XRectangle rect;
int dw, dh;
XtVaGetValues(paint, XtNdrawWidth, &dw, XtNdrawHeight, &dh, NULL);
rect.x = 0;
rect.y = 0;
rect.width = dw;
rect.height = dh;
PwRegionSet(paint, &rect, None, None);
setToSelectOp();
}
void StdUndoCallback(Widget w, XtPointer paintArg, XtPointer junk2)
{
UndoSwap((Widget)paintArg);
}
void ClipboardSetImage(Widget w, Image *image)
{
if (Global.region.pix != None)
XFreePixmap(XtDisplay(w), Global.region.pix);
if (Global.region.mask != None)
XFreePixmap(XtDisplay(w), Global.region.mask);
if (Global.region.image != NULL)
ImageDelete(Global.region.image);
Global.region.pix = None;
Global.region.mask = None;
Global.region.cmap = None;
Global.region.image = (void*)image;
Global.region.width = image->width;
Global.region.height = image->height;
}
/*
** End of "edit" menu function, start region menu functions.
**
*/
void StdRegionFlipX(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
float v = -1.0;
PwRegionAddScale(paint, &v, NULL);
}
void StdRegionFlipY(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
float v = -1.0;
PwRegionAddScale(paint, NULL, &v);
}
/*
**
*/
static void stdImgProcess(Widget paint, Image *(*func)(Image *))
{
Pixmap pix;
Colormap cmap;
Image *in, *out;
StateSetBusy(True);
if (!PwRegionGet(paint, &pix, None)) {
StateSetBusy(False);
return;
}
PwRegionTear(paint);
XtVaGetValues(paint, XtNcolormap, &cmap, NULL);
in = PixmapToImage(paint, pix, cmap);
out = func(in);
ImageDelete(in);
ImageToPixmapCmap(out, paint, &pix, cmap);
PwRegionSetRawPixmap(paint, pix);
StateSetBusy(False);
}
void StdRegionInvert(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
stdImgProcess(paint, ImageInvert);
}
void StdRegionSharpen(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
stdImgProcess(paint, ImageSharpen);
}
void StdRegionSmooth(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
stdImgProcess(paint, ImageSmooth);
}
void StdRegionEdge(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
stdImgProcess(paint, ImageEdge);
}
void StdRegionEmbose(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
stdImgProcess(paint, ImageEmbose);
}
void StdRegionOilPaint(Widget w, XtPointer paintArg, XtPointer junk2)
{
Widget paint = (Widget)paintArg;
stdImgProcess(paint, ImageOilPaint);
}
/*
** Start callback functions
*/
static void prCallback(Widget paint, Widget w, Boolean flag)
{
XtVaSetValues(w, XtNsensitive, flag, NULL);
}
static void addFunction(Widget item, Widget paint, XtCallbackProc func)
{
XtAddCallback(item, XtNcallback, func, (XtPointer)paint);
XtAddCallback(paint, XtNregionCallback, (XtCallbackProc)prCallback, (XtPointer)item);
XtVaSetValues(item, XtNsensitive, (XtPointer)False, NULL);
}
void ccpAddUndo(Widget w, Widget paint)
{
XtAddCallback(w, XtNcallback, StdUndoCallback, (XtPointer)paint);
}
void ccpAddCut(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdCutCallback);
}
void ccpAddCopy(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdCopyCallback);
}
void ccpAddPaste(Widget w, Widget paint)
{
XtVaSetValues(w, XtNsensitive, True, NULL);
XtAddCallback(w, XtNcallback,
(XtCallbackProc)StdPasteCallback, (XtPointer)paint);
}
void ccpAddClear(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdClearCallback);
}
void ccpAddDuplicate(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdDuplicateCallback);
}
/*
** Region functions
*/
void ccpAddSaveRegion(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdSaveRegionFile);
}
void ccpAddRegionFlipX(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdRegionFlipX);
}
void ccpAddRegionFlipY(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdRegionFlipY);
}
void ccpAddRegionInvert(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdRegionInvert);
}
void ccpAddRegionSharpen(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdRegionSharpen);
}
void ccpAddRegionSmooth(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdRegionSmooth);
}
void ccpAddRegionEdge(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdRegionEdge);
}
void ccpAddRegionEmbose(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdRegionEmbose);
}
void ccpAddRegionOilPaint(Widget w, Widget paint)
{
addFunction(w, paint, (XtCallbackProc)StdRegionOilPaint);
}
/*
** Standard poup menu
*/
static PaintMenuItem popupMenu[] = {
MI_SEPERATOR(),
#define P_UNDO_ITEM 1
MI_SIMPLE("undo"),
MI_SEPERATOR(),
#define P_CUT_ITEM 3
MI_SIMPLE("cut"),
#define P_COPY_ITEM 4
MI_SIMPLE("copy"),
#define P_PASTE_ITEM 5
MI_SIMPLE("paste"),
#define P_CLEAR_ITEM 6
MI_SIMPLE("clear"),
};
void ccpAddStdPopup(Widget paint)
{
MenuPopupCreate(XtParent(paint), XtNumber(popupMenu), popupMenu);
ccpAddUndo(popupMenu[P_UNDO_ITEM].widget, paint);
ccpAddCut(popupMenu[P_CUT_ITEM].widget, paint);
ccpAddCopy(popupMenu[P_COPY_ITEM].widget, paint);
ccpAddPaste(popupMenu[P_PASTE_ITEM].widget, paint);
ccpAddClear(popupMenu[P_CLEAR_ITEM].widget, paint);
}